package com.enation.app.javashop.buyer.api.passport;

import com.dag.eagleshop.core.account.model.dto.account.AccountDTO;
import com.dag.eagleshop.core.account.model.dto.account.OpenAccountDTO;
import com.dag.eagleshop.core.account.model.dto.member.OpenMemberDTO;
import com.dag.eagleshop.core.account.model.dto.member.OpenMemberIdentityDTO;
import com.dag.eagleshop.core.account.model.enums.AccountTypeEnum;
import com.dag.eagleshop.core.account.model.enums.IdentityTypeEnum;
import com.dag.eagleshop.core.account.model.enums.NatureEnum;
import com.dag.eagleshop.core.account.service.AccountManager;
import com.enation.app.javashop.core.base.SceneType;
import com.enation.app.javashop.core.client.distribution.CommissionTplClient;
import com.enation.app.javashop.core.client.distribution.DistributionClient;
import com.enation.app.javashop.core.client.system.CaptchaClient;
import com.enation.app.javashop.core.client.system.SmsClient;
import com.enation.app.javashop.core.distribution.model.dos.CommissionTpl;
import com.enation.app.javashop.core.distribution.model.dos.DistributionDO;
import com.enation.app.javashop.core.distribution.service.DistributionManager;
import com.enation.app.javashop.core.member.MemberErrorCode;
import com.enation.app.javashop.core.member.model.dos.Member;
import com.enation.app.javashop.core.member.model.dto.MemberDTO;
import com.enation.app.javashop.core.member.model.dto.MemberQueryParam;
import com.enation.app.javashop.core.member.model.dto.MemberWapDTO;
import com.enation.app.javashop.core.member.model.vo.MemberVO;
import com.enation.app.javashop.core.member.service.MemberManager;
import com.enation.app.javashop.core.passport.service.PassportManager;
import com.enation.app.javashop.framework.JavashopConfig;
import com.enation.app.javashop.framework.context.ThreadContextHolder;
import com.enation.app.javashop.framework.database.Page;
import com.enation.app.javashop.framework.exception.ServiceException;
import com.enation.app.javashop.framework.util.StringUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.assertj.core.util.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import javax.validation.constraints.NotEmpty;
import java.util.List;


/**
 * 会员登录注册API
 *
 * @author zh
 * @version v7.0
 * @since v7.0
 * 2018年3月23日 上午10:12:12
 */
@RestController
@RequestMapping("/passport")
@Api(description = "会员注册API")
@Validated
public class PassportRegisterBuyerController {

    @Autowired
    private PassportManager passportManager;
    @Autowired
    private CaptchaClient captchaClient;
    @Autowired
    private MemberManager memberManager;
    @Autowired
    private SmsClient smsClient;
    @Autowired
    private JavashopConfig javashopConfig;
    @Autowired
    private CommissionTplClient commissionTplClient;
    @Autowired
    private DistributionClient distributionClient;
    @Autowired
    private AccountManager accountManager;
    @Autowired
    private DistributionManager distributionManager;

    @PostMapping(value = "/register/smscode/{mobile}")
    @ApiOperation(value = "发送验证码")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "uuid", value = "uuid客户端的唯一标识", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "captcha", value = "图片验证码", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "mobile", value = "手机号码", required = true, dataType = "String", paramType = "path"),
    })
    public String smsCode(@NotEmpty(message = "uuid不能为空") String uuid, @NotEmpty(message = "图片验证码不能为空") String captcha, @PathVariable("mobile") String mobile) {
        boolean isPass = captchaClient.valid(uuid, captcha, SceneType.REGISTER.name());
        if (!isPass) {
            throw new ServiceException(MemberErrorCode.E107.code(), "图片验证码不正确！");
        }
        passportManager.sendRegisterSmsCode(mobile);
        //清除缓存图片验证码信息
        captchaClient.deleteCode(uuid, captcha, SceneType.REGISTER.name());
        return javashopConfig.getSmscodeTimout() / 60 + "";
    }

    @PostMapping("/register/pc")
    @ApiOperation(value = "PC注册")
    public MemberVO registerForPC(@Valid MemberDTO memberDTO) {
        boolean bool = smsClient.valid(SceneType.REGISTER.name(), memberDTO.getMobile(), memberDTO.getSmsCode());
        if (!bool) {
            throw new ServiceException(MemberErrorCode.E107.code(), "短信验证码错误");
        }
        //对用户名的校验处理
        String username = memberDTO.getUsername();
        if (username.contains("@")) {
            throw new ServiceException(MemberErrorCode.E107.code(), "用户名中不能包含@等特殊字符！");
        }
        Member member = new Member();
        member.setUname(memberDTO.getUsername());
        member.setPassword(memberDTO.getPassword());
        member.setNickname(memberDTO.getUsername());
        member.setMobile(memberDTO.getMobile());
        member.setSex(1);
        member.setRegisterIp(ThreadContextHolder.getHttpRequest().getRemoteAddr());
        //注册
        memberManager.register(member);
        //登录
        return memberManager.login(member.getUname(), memberDTO.getPassword(),1);

    }


    @PostMapping("/memberInit")
    @ApiOperation(value = "会员分销商初始化")
    public boolean memberInit() {
        //注册
        MemberQueryParam memberQueryParam = new MemberQueryParam();
        memberQueryParam.setPageNo(1);
        memberQueryParam.setPageSize(100000);
        Page page = memberManager.list(memberQueryParam);
        List<Member> list = page.getData();
        for (Member member : list) {
            DistributionDO distributionDO = distributionClient.getDistributorByMemberId(member.getMemberId());
            if(distributionDO == null){
                DistributionDO distributor = new DistributionDO();
                distributor.setMemberId(member.getMemberId());
                CommissionTpl commissionTpl = commissionTplClient.getDefaultCommission();
                if(commissionTpl == null){
                    commissionTpl = new CommissionTpl();
                    commissionTpl.setId(0);
                    commissionTpl.setTplName("空模板");
                }
                distributor.setCurrentTplId(commissionTpl.getId());
                distributor.setCurrentTplName(commissionTpl.getTplName());
                distributor.setMemberName(member.getUname());
                distributor.setDistributorGrade(1);
                distributor.setDistributorTitle("运营经理");
                distributor.setStatus(1);
                // 随机一个邀请码
                distributor.setInviteCode(distributionManager.randomInviteCode());
                distributor = this.distributionClient.add(distributor);
                distributor.setPath("0|" + distributor.getMemberId() + "|");
                this.distributionClient.edit(distributor);
            }else{
                // 如果邀请码是空的 生成邀请码
                String inviteCode = distributionDO.getInviteCode();
                if(StringUtil.isEmpty(inviteCode)){
                    distributionDO.setInviteCode(distributionManager.randomInviteCode());
                    this.distributionClient.edit(distributionDO);
                }
            }

            // 开通会员
            if(StringUtil.isEmpty(member.getAccountMemberId())){
                OpenMemberDTO openMemberDTO = new OpenMemberDTO();
                openMemberDTO.setMobile(member.getMobile());
                openMemberDTO.setMemberName(member.getNickname());
                // 设置会员身份
                OpenMemberIdentityDTO memberIdentityDTO = new OpenMemberIdentityDTO();
                memberIdentityDTO.setIdentityType(IdentityTypeEnum.BUYER.getIndex());
                memberIdentityDTO.setIdentityName(IdentityTypeEnum.BUYER.getText());
                openMemberDTO.setIdentityList(Lists.newArrayList(memberIdentityDTO));
                com.dag.eagleshop.core.account.model.dto.member.MemberDTO memberDTO = accountManager.openMember(openMemberDTO);

                // 开通账户
                OpenAccountDTO openAccountDTO = new OpenAccountDTO();
                openAccountDTO.setAccountType(AccountTypeEnum.MEMBER_MASTER.getIndex());
                openAccountDTO.setAccountTypeName(AccountTypeEnum.MEMBER_MASTER.getText());
                openAccountDTO.setMemberId(memberDTO.getId());
                openAccountDTO.setNature(NatureEnum.PERSONAL.getIndex());
                openAccountDTO.setOperatorName(member.getUname());
                AccountDTO accountDTO = accountManager.openAccount(openAccountDTO);

                // 开通押金账户
                OpenAccountDTO openDepositAccountDTO = new OpenAccountDTO();
                openDepositAccountDTO.setAccountType(AccountTypeEnum.DEPOSIT.getIndex());
                openDepositAccountDTO.setAccountTypeName(AccountTypeEnum.DEPOSIT.getText());
                openDepositAccountDTO.setMemberId(memberDTO.getId());
                openDepositAccountDTO.setNature(NatureEnum.PERSONAL.getIndex());
                openDepositAccountDTO.setOperatorName(member.getUname());
                AccountDTO depositAccountDTO = accountManager.openAccount(openDepositAccountDTO);

                // 更新本地会员和账户会员映射关系表
                member.setAccountMemberId(accountDTO.getMemberId());
                memberManager.edit(member, member.getMemberId());
            }else{
                com.dag.eagleshop.core.account.model.dto.member.MemberDTO memberDTO = accountManager.queryMemberById(member.getAccountMemberId());
                if(memberDTO == null){
                    OpenMemberDTO openMemberDTO = new OpenMemberDTO();
                    openMemberDTO.setMobile(member.getMobile());
                    openMemberDTO.setMemberName(member.getNickname());
                    // 设置会员身份
                    OpenMemberIdentityDTO memberIdentityDTO = new OpenMemberIdentityDTO();
                    memberIdentityDTO.setIdentityType(IdentityTypeEnum.BUYER.getIndex());
                    memberIdentityDTO.setIdentityName(IdentityTypeEnum.BUYER.getText());
                    openMemberDTO.setIdentityList(Lists.newArrayList(memberIdentityDTO));
                    memberDTO = accountManager.openMember(openMemberDTO);
                    // 更新本地会员和账户会员映射关系表
                    member.setAccountMemberId(memberDTO.getId());
                    memberManager.edit(member, member.getMemberId());
                }

                // 补开主账户
                AccountDTO accountDTO = accountManager.queryByMemberIdAndAccountType(member.getAccountMemberId(), AccountTypeEnum.MEMBER_MASTER.getIndex());
                if(accountDTO == null){
                    // 开通账户
                    OpenAccountDTO openAccountDTO = new OpenAccountDTO();
                    openAccountDTO.setAccountType(AccountTypeEnum.MEMBER_MASTER.getIndex());
                    openAccountDTO.setAccountTypeName(AccountTypeEnum.MEMBER_MASTER.getText());
                    openAccountDTO.setMemberId(memberDTO.getId());
                    openAccountDTO.setNature(NatureEnum.PERSONAL.getIndex());
                    openAccountDTO.setOperatorName(member.getUname());
                    accountDTO = accountManager.openAccount(openAccountDTO);
                }

                // 补开押金账户
                AccountDTO depositAccountDTO = accountManager.queryByMemberIdAndAccountType(member.getAccountMemberId(), AccountTypeEnum.DEPOSIT.getIndex());
                if(depositAccountDTO == null){
                    OpenAccountDTO openDepositAccountDTO = new OpenAccountDTO();
                    openDepositAccountDTO.setAccountType(AccountTypeEnum.DEPOSIT.getIndex());
                    openDepositAccountDTO.setAccountTypeName(AccountTypeEnum.DEPOSIT.getText());
                    openDepositAccountDTO.setMemberId(memberDTO.getId());
                    openDepositAccountDTO.setNature(NatureEnum.PERSONAL.getIndex());
                    openDepositAccountDTO.setOperatorName(member.getUname());
                    depositAccountDTO = accountManager.openAccount(openDepositAccountDTO);
                }
            }
        }
        return true;
    }


    @PostMapping("/register/wap")
    @ApiOperation(value = "wap注册")
    public MemberVO registerForWap(@Valid MemberWapDTO memberDTO) {
        String mobile = memberDTO.getMobile();
        String password = memberDTO.getPassword();
        String validMobile = this.smsClient.validMobile(SceneType.REGISTER.name(),mobile);

        if(StringUtil.isEmpty(validMobile) || !mobile.equals(validMobile)){
            throw new ServiceException(MemberErrorCode.E115.code(), "请先对手机进行验证");
        }

        Member member = new Member();
        member.setMobile(mobile);
        member.setSex(1);
        member.setPassword(password);
        member.setUname("m_" + mobile);
        member.setNickname("m_" + mobile);
        member.setRegisterIp(ThreadContextHolder.getHttpRequest().getRemoteAddr());
        // 会员位置信息
        // String position = memberDTO.getPosition();
        // if(!StringUtils.isEmpty(position)){
        //     MemberPosition memberPosition = JSON.parseObject(position, MemberPosition.class);
        //     member.setProvince(memberPosition.getProvince());
        //     member.setCity(memberPosition.getCity());
        //     member.setCounty(memberPosition.getDistrict());
        //     member.setTown(memberPosition.getStreet());
        //     member.setAddress(memberPosition.getAddress());
        //     if(StringUtils.isEmpty(memberPosition.getBuildingPosition())){
        //         String[] split = memberPosition.getBuildingPosition().split(",");
        //         member.setLat(Double.valueOf(split[1]));
        //         member.setLng(Double.valueOf(split[0]));
        //     }
        // }
        //注册
        memberManager.register(member);
        //获取token
        return memberManager.login(member.getUname(), password,1);
    }

}
